﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Script.Serialization;

namespace UnitTests
{
    public class TestTask
    {
        public TestTask()
        {
            Properties = new Dictionary<string, string>();
        }
        public Dictionary<string, string> Properties { get; set; }

        public void ExecuteTask(string filename)
        {
            var js = new JavaScriptSerializer();
            var json = File.ReadAllText(filename);
            var objectGraph = js.DeserializeObject(json);

            var dicts = ((object[])objectGraph).OfType<Dictionary<string, object>>();

            foreach (var dict in dicts.Select(ReduceNesting))
            {
                var backup = BackupProperties(dict);
                SetProperties(dict);
                DoStuff();
                RestoreProperties(backup);
            }
        }

        private void DoStuff()
        {
            foreach (var property in Properties)
            {
                Console.WriteLine(property.Key+": "+property.Value);
            }
        }


        private Dictionary<string, object> ReduceNesting(Dictionary<string, object> jsobj)
        {
            var dict = new Dictionary<string, object>();
            foreach (var kvp in jsobj)
            {
                if (kvp.Value is Dictionary<string, object>)
                {
                    var val = kvp.Value as Dictionary<string, object>;
                    var reducedDict = ReduceNesting(val);
                    foreach (var kvp2 in reducedDict)
                    {
                        dict[kvp.Key + "." + kvp2.Key] = kvp2.Value;
                    }
                }
                else
                {
                    dict[kvp.Key] = kvp.Value;
                }
            }
            return dict;
        }

        private void RestoreProperties(Dictionary<string, string> backup)
        {
            foreach (var kvp in backup)
            {
                if (kvp.Value == null)
                {
                    Properties.Remove(kvp.Key);
                }
                else
                {
                    Properties[kvp.Key] = kvp.Value;
                }
            }
        }

        private Dictionary<string, string> BackupProperties(Dictionary<string, object> configObj)
        {
            return configObj.ToDictionary(
                pair => pair.Key,
                pair => (Properties.ContainsKey(pair.Key))
                            ? Properties[pair.Key]
                            : null
                );
        }

        private void SetProperties(Dictionary<string, object> configObj)
        {
            foreach (var kvp in configObj)
            {
                Properties[kvp.Key] = ExpandProperties(kvp.Value.ToString());

                //Properties.ExpandProperties(kvp.Value.ToString(), Location);
            }
        }

        private string ExpandProperties(string toString)
        {
            return Properties.Aggregate(toString, (current, pair) => current.Replace("${" + pair.Key + "}", pair.Value));
        }
    }
}